import { IPluginErrorType } from '@lobehub/chat-plugin-sdk';
import type { PartialDeep } from 'type-fest';
import { z } from 'zod';

import { LobeToolRenderType } from '../../tool';

// ToolIntervention must be defined first to avoid circular dependency
export interface ToolIntervention {
  rejectedReason?: string;
  status?: 'pending' | 'approved' | 'rejected' | 'aborted' | 'none';
}

export const ToolInterventionSchema = z.object({
  rejectedReason: z.string().optional(),
  status: z.enum(['pending', 'approved', 'rejected', 'aborted', 'none']).optional(),
});

export interface ChatPluginPayload {
  apiName: string;
  arguments: string;
  identifier: string;
  intervention?: ToolIntervention;
  type: LobeToolRenderType;
}

export interface ChatToolPayload {
  apiName: string;
  arguments: string;
  id: string;
  identifier: string;
  intervention?: ToolIntervention;
  result_msg_id?: string;
  thoughtSignature?: string;
  type: LobeToolRenderType;
}

/**
 * Tool execution result from tool messages
 */
export interface ChatToolResult {
  content: string | null;
  error?: any;
  id: string;
  state?: any;
}

/**
 * Chat tool payload with merged execution result
 */
export interface ChatToolPayloadWithResult extends ChatToolPayload {
  intervention?: ToolIntervention;
  result?: ChatToolResult;
  result_msg_id?: string;
}

export interface ToolsCallingContext {
  topicId?: string;
}
/**
 * The function that the model called.
 */
export interface ToolFunction {
  /**
   * The arguments to call the function with, as generated by the model in JSON
   * format. Note that the model does not always generate valid JSON, and may
   * hallucinate parameters not defined by your function schema. Validate the
   * arguments in your code before calling your function.
   */
  arguments: string;

  /**
   * The name of the function to call.
   */
  name: string;
}

export interface MessageToolCall {
  /**
   * The function that the model called.
   */
  function: ToolFunction;

  /**
   * The ID of the tool call.
   */
  id: string;

  thoughtSignature?: string;
  /**
   * The type of the tool. Currently, only `function` is supported.
   */
  type: 'function' | string;
}

export type MessageToolCallChunk = PartialDeep<MessageToolCall> & { index: number };

export const MessageToolCallSchema = z.object({
  function: z.object({
    arguments: z.string(),
    name: z.string(),
  }),
  id: z.string(),
  type: z.string(),
});

export const ChatToolPayloadSchema = z.object({
  apiName: z.string(),
  arguments: z.string(),
  id: z.string(),
  identifier: z.string(),
  intervention: ToolInterventionSchema.optional(),
  result_msg_id: z.string().optional(),
  thoughtSignature: z.string().optional(),
  type: z.string(),
});

/**
 * Chat message error object
 */
export interface ChatMessagePluginError {
  body?: any;
  message: string;
  type: IPluginErrorType;
}
